<?php
namespace Home\Controller;

class WeChatController extends HomeController {
	private $appid;
	private $data;
	
	function index() {
		$this->appid = $_GET['appid'];
		empty($this->appid) && exit;
		//验证消息真实性
		if ($this->init()) {
			//如果有echostr 说明是验证服务器归属权
			if (isset($_GET['echostr'])) {
				//记录服务器验证信息
				$model = M('WechatApp');
				$data['verified']     = 1;
				$data['verify_time'] = NOW_TIME;
				$model->where('id='.$this->appid)->save($data);
				exit($_GET['echostr']);
			}
			$this->msgRouter();
		}
	}
	
	function __get($key) {
		return $this->data[$key];
	}
	//校验signature
	private function init() {
		$signature = $_GET['signature'];
		$timestamp = $_GET['timestamp'];
		$nonce     = $_GET['nonce'];
		if (empty($signature) || empty($timestamp) || empty($nonce)) {
			return false;
		}
		static $appList;
		/* 获取缓存数据 */
		empty($appList) && $appList = S('sys_app_list');
		$key = $this->appid;
		/* 已经缓存则直接使用缓存信息 */
		if (isset($appList[$key])) {
			$token = $appList[$key];
		}else {
			$model = M('WechatApp');
			$map['id'] = $this->appid;
			$token = $model->where($map)->getField('token');
			//赋值，并添加到缓存中去
			$appList[$key] = $token;
			$count = count($appList);
			$max   = C('USER_MAX_CACHE');
			while ($count-- > $max) {
				array_shift($appList);
			}
			S('sys_app_list', $appList);
		}
		if (!$token) return false;
		$tmpArr = array($token, $timestamp, $nonce);
		sort($tmpArr);
		$tmpStr = implode($tmpArr);
		$tmpStr = sha1($tmpStr);
	
		if($tmpStr == $signature){
			$this->appDec();
			return true;
		}else{
			return false;
		}
	}
	
	//响应次数 -1
	private function appDec() {
		$map['appid'] = $this->appid;
		$map['connect'] = array('gt', 0);
		$dec = M('WechatQuota')->where($map)->setDec('connect');
		if (!$dec) {
			$this->sendText('此公众号响应次数已经用完！'.$dec);
			exit();
		}
	}
	
	//消息调度
	private function msgRouter() {
		//$_POST 不能识别xml数据包，所以使用 $GLOBALS["HTTP_RAW_POST_DATA"]
		$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
		if (!empty($postStr)) {
			$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
			//将数据对象转换为数组
			$postArr = (array)$postObj;
			$this->data = $postArr;
			//根据消息类型，分派到返回信息处理部分
			switch ($postArr['MsgType']) {
				case 'event' :
					$this->_event();
					break;
				case 'text' :
					$this->_text();
					break;
				case 'image' :
					break;
				case 'voice' :
					break;
				case 'video' :
					break;
				case 'location' :
					break;
				case 'link' :
					break;
				default : $this->_text();
			}
		}else {
			exit;
		}
	}
	//处理事件推送
	private function _event() {
		$data = $this->data;
		//关注事件
		if ($data['Event']=='subscribe') {
			$map['appid'] = $this->appid;
			$content = M('ReplyAttention')->where($map)->getField('content');
			$this->sendText($content);
		}
		//取消关注
		if ($data['Event']=='unsubscribe') {
			exit;
		}
	}
	
	private function sendText($content) {
		$textTpl = "<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[%s]]></Content></xml>";
		$data = $this->data;
		$resultStr = sprintf($textTpl, $data['FromUserName'], $data['ToUserName'], time(), $content);
		echo $resultStr;
	}
	
	private function sendMusic($title, $url) {
		$musicTpl = "<xml>
		<ToUserName><![CDATA[%s]]></ToUserName>
		<FromUserName><![CDATA[%s]]></FromUserName>
		<CreateTime>%s</CreateTime>
		<MsgType><![CDATA[music]]></MsgType>
		<Music>
		<Title><![CDATA[%s]]></Title>
		<Description><![CDATA[%s]]></Description>
		<MusicUrl><![CDATA[%s]]></MusicUrl>
		<HQMusicUrl><![CDATA[%s]]></HQMusicUrl>
		</Music>
		</xml>";
		//$musicTpl = "<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[music]]></MsgType><Music><Title><![CDATA[%s]]></Title><Description><![CDATA[%s]]></Description><MusicUrl><![CDATA[%s]]></MusicUrl><HQMusicUrl><![CDATA[%s]]></HQMusicUrl><ThumbMediaId><![CDATA[200042309]]></ThumbMediaId></Music></xml>";
		$data = $this->data;
		$resultStr = sprintf($musicTpl, $data['FromUserName'], $data['ToUserName'], time(), $title, $title, $url, $url);
		echo $resultStr;
	}
	
	private function _text() {
		$keyword = $this->data['Content'];
		$reply   = $this->autoChat($keyword, 'simsimi');
		$this->sendText($reply);
	}
	
	private function autoChat($keyword, $type='simsimi') {
		$model = M('Reply');
		$map['appid'] = $this->appid;
		$map['keyword'] = (string)$keyword;
		$reply = $model->where($map)->select();
		//首先查询库内是否定义了自定义回复
		if ($reply) {
			shuffle($reply);
 			$result = M('reply_'.$reply[0]['type'])->find($reply[0]['id']);
 			$return = $result['content'];
		}else {
			switch ($type) {
				case 'xiaohuangji' :
					/* 小黄鸡(www.xiaohuangji.com)聊天 */
					$data    = array('para' => $keyword);
					$return = POST('http://www.xiaohuangji.com/ajax.php', $data);
				break;
				case 'ajaxsns' :
					/* ajaxsns聊天 */
					$url = 'http://api.ajaxsns.com/api.php';
					$get = array(
						'key' => 'free',
						'appid' => 0,
						'msg'   => urlencode($keyword)
					);
					$content = (array)json_decode(GET($url, $get));
					$return = str_replace('{br}', "\n", $content['content']);
					break;
				case 'simsimi' :
					$url = 'http://www.simsimi.com/func/req';
					$data = array(
						'msg' => $keyword,
						'lc'  => 'ch'
					);
					$json = (array)json_decode(GET($url, $data));
					$return = $json['response'];
					break;
				default: $return = '没有定义回答';
			}
		}
		return $return;
	}
	
	function musicSearch($title) {
		$url = 'http://box.zhangmen.baidu.com/x';
    	$prase = array(
    			'op' => 12,
    			'count' => 1,
    			'title' => $title.'$$',
    	);
    	$obj = (array)simplexml_load_string(GET($url,$prase), 'SimpleXMLElement', LIBXML_NOCDATA);
    	$urlobj = $obj['url'];
    	shuffle($urlobj);
    	$music  = (array)$urlobj[0];
    	$url = substr($music['encode'], 0, strrpos($music['encode'],'/')+1).$music['decode'];;
	}
}